package model;
import java.io.ObjectStreamException;
import java.io.PrintStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class ArrayDeclaration implements StatementKind{
	  // State variables.
	  private final int length;
	  private final Class<?> elementType;
	  
	  
	  private List<Class<?>> inputTypesCached;
	  private Class<?> outputTypeCached;    
	  private int hashCodeCached;
	  private boolean hashCodeComputed= false;

	  public ArrayDeclaration(Class<?> elementType, int length) {

		    // Check legality of arguments.
		    if (elementType == null) throw new IllegalArgumentException("elementType cannot be null.");
		    if (length < 0) throw new IllegalArgumentException("arity cannot be less than zero: " + length);

		    // Set state variables.
		    this.elementType = elementType;
		    this.length = length;
		  }
	  public Class<?> getElementType() {
		    return this.elementType;
		  }

		  /**
		   * Extracts the input constraints for this ArrayDeclarationInfo
		   * @return list of input constraints
		   */
		  public List<Class<?>> getInputTypes() {
		    if (inputTypesCached == null) {
		      this.inputTypesCached = new ArrayList<Class<?>>(length);
		      for (int i = 0 ; i < length ; i++)
		        inputTypesCached.add(elementType);
		      inputTypesCached = Collections.unmodifiableList(inputTypesCached);
		    }
		    return Collections.unmodifiableList(this.inputTypesCached);
		  }
		  @Override
		  public String toString() {
		    return "array_of_" + this.elementType.getSimpleName() + "_of_size_" + this.length;
		  }

		  public Class<?> getOutputType() {
			    if (outputTypeCached == null) {
			      outputTypeCached = Array.newInstance(elementType, 0).getClass();
			    }
			    return outputTypeCached;
			  }
		  public String toParseableString(Map<String,Class<?>> classesToTest) {
			    return elementType.getName() + "[" + Integer.toString(length) + "]";
			  }
		  public String convertString(){
			  return toString();
		  }

}
